package vn.edu.saigontech.ncms.model.info;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.OptimisticLockType;

import vn.edu.saigontech.ncms.model.BaseEntity;
import vn.edu.saigontech.ncms.model.system.Money;
import vn.edu.saigontech.ncms.model.system.ReceiptAbstractDiscountItem;
import vn.edu.saigontech.ncms.model.user.User;

@Entity
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true, optimisticLock = OptimisticLockType.ALL)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "submitted_type", discriminatorType = DiscriminatorType.STRING)
@Table(name = "ncms_receipt")
@SuppressWarnings("serial")
public abstract class AbstractReceipt extends BaseEntity {
	
	@Column(name = "number")
	protected String number;

	//@Temporal(TemporalType.DATE)
	@Column(name = "date", nullable = false)
	protected Date date;

	@Embedded
	@AttributeOverrides( {
			@AttributeOverride(name = "amount", column = @Column(name = "fee")),
			@AttributeOverride(name = "currency", column = @Column(name = "fee_currency")), })
	protected Money fee;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "cashier_id", nullable = false)
	protected User cashier;

	@Column(name = "active")
	protected boolean active;

	@Column(name = "comment", length = 4000)
	protected String comment;

	@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "receipt")
	@org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
	protected OfferingMember member;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "student_id", nullable = false)
	protected Student student;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "offering_id", nullable = false)
	protected Offering offering;

	@ManyToOne
	@JoinColumn(name = "discount_item")
	protected ReceiptAbstractDiscountItem discountItem;
	
	@ManyToOne
	@JoinColumn(name = "discount_item2")
	protected ReceiptAbstractDiscountItem discountItem2;

	@ManyToOne
	@JoinColumn(name = "receipt_maintenance")
	protected ReceiptMaintenance receiptMaintenance;
	
	@ManyToOne
	@JoinColumn(name = "receipt_refund")
	protected ReceiptRefund receiptRefund;
	
	public String getReceiptComment() {
		StringBuffer buffer = new StringBuffer();
		List<String> list = new ArrayList<String>();
		if(this.receiptMaintenance != null) {
			list.add("Bảo lưu từ biên lai số \"" + this.receiptMaintenance.getNumber() + "\"");
		}
		if(this.discountItem != null) {
			list.add(this.discountItem.getName());
		}
		if(this.discountItem2 != null) {
			list.add(this.discountItem2.getName());
		}
		if(!this.comment.isEmpty()) {
			list.add(this.comment);
		}
		for(int i = 0; i < list.size(); i++) {
			if(i != list.size() - 1)
				buffer.append(list.get(i) + ", ");
			else buffer.append(list.get(i));
		}
		return buffer.toString();
	}

	public OfferingMember getOfferingMember() {
		for (OfferingMember each : this.getOffering().getMembers()) {
			if (each.getReceipt().getStudent() == this.getStudent()) {
				return each;
			}
		}
		return null;
	}
	
	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public Money getFee() {
		return fee;
	}

	public void setFee(Money fee) {
		this.fee = fee;
	}

	public User getCashier() {
		return cashier;
	}

	public void setCashier(User cashier) {
		this.cashier = cashier;
	}

	public boolean isActive() {
		return active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public OfferingMember getMember() {
		return member;
	}

	public void setMember(OfferingMember member) {
		this.member = member;
	}

	public Student getStudent() {
		return student;
	}

	public void setStudent(Student student) {
		this.student = student;
	}

	public Offering getOffering() {
		return offering;
	}

	public void setOffering(Offering offering) {
		this.offering = offering;
	}

	public ReceiptAbstractDiscountItem getDiscountItem() {
		return discountItem;
	}

	public void setDiscountItem(ReceiptAbstractDiscountItem discountItem) {
		this.discountItem = discountItem;
	}

	public ReceiptMaintenance getReceiptMaintenance() {
		return receiptMaintenance;
	}

	public void setReceiptMaintenance(ReceiptMaintenance receiptMaintenance) {
		this.receiptMaintenance = receiptMaintenance;
	}

	public ReceiptRefund getReceiptRefund() {
		return receiptRefund;
	}

	public void setReceiptRefund(ReceiptRefund receiptRefund) {
		this.receiptRefund = receiptRefund;
	}
	
	public ReceiptAbstractDiscountItem getDiscountItem2() {
		return discountItem2;
	}

	public void setDiscountItem2(ReceiptAbstractDiscountItem discountItem2) {
		this.discountItem2 = discountItem2;
	}
}